package de.stefanocke.roo.xtend

import java.util.List
import org.apache.felix.ipojo.parser.FieldMetadata
import org.springframework.roo.classpath.details.IdentifiableAnnotatedJavaStructure
import org.springframework.roo.classpath.details.MethodMetadata
import org.springframework.roo.classpath.details.annotations.AnnotatedJavaType
import org.springframework.roo.classpath.details.annotations.AnnotationMetadata
import org.springframework.roo.model.DataType
import org.springframework.roo.model.JavaPackage
import org.springframework.roo.model.JavaSymbolName
import org.springframework.roo.model.JavaType

import static extension de.stefanocke.roo.xtend.Counter.*
import static extension de.stefanocke.roo.xtend.RooExtensions.*
import static extension de.stefanocke.roo.xtend.Parameter.*


class RooExtensions {
	
	def static javaType(String fqn){
		new JavaType(fqn)
	}
	
	def static javaType(Class clazz){
		new JavaType(clazz)
	}
	
	def static javaType(Class clazz, String parameterFqn){
		javaType(clazz.name, parameterFqn.javaType)
	}
	
	def static javaType(String fqn, String parameterFqn){
		javaType(fqn, parameterFqn.javaType)
	}
	
	def static javaType(String fqn, JavaType ... parameter){
		javaType(fqn, newArrayList(parameter))
	}
	
	def static javaType(Class clazz, JavaType parameter){
		javaType(clazz.name, newArrayList(parameter))
	}
	
	def static wildcardExtends(JavaType type){
		new JavaType(type.fqn, 0, type.dataType, JavaType::WILDCARD_EXTENDS, type.parameters)
	}
	
	def static wildcardSuper(JavaType type){
		new JavaType(type.fqn, 0, type.dataType, JavaType::WILDCARD_EXTENDS, type.parameters)
	}
	
	def static array(JavaType type){
		new JavaType(type.fqn, 1, type.dataType, null, null)
	}
	
	
	public static JavaType WILDCARD = new JavaType(JavaType::OBJECT.fqn, 0, DataType::TYPE, JavaType::WILDCARD_NEITHER, null)
	
	
	def static javaType(String fqn, JavaType param1, JavaType param2 ){
		javaType(fqn, newArrayList(param1, param2))
	}
	def static javaType(String fqn, JavaType param1, JavaType param2, JavaType param3){
		javaType(fqn, newArrayList(param1, param2, param3))
	}
	
	def static javaType(String fqn, List<JavaType> parameters){
		new JavaType(fqn, 0, DataType::TYPE, null, parameters)
	}
	
	def static wrapIfPrimitive(JavaType type){
		if(type.primitive){
			javaType(type.fullyQualifiedTypeName)
		} else {
			type
		}
	}
	def static fqn(JavaType type){
		type.fullyQualifiedTypeName
	}
	
	def static annoJavaType(JavaPackage p){
		p.fullyQualifiedPackageName
	}
	
	def static annoJavaType(JavaType type, List<AnnotationMetadata> annotations){
		new AnnotatedJavaType(type, annotations)
	}
	
	def static annoJavaType(String fqn, List<AnnotationMetadata> annotations){
		fqn.javaType.annoJavaType(annotations)
	}
		

	def static fqnAppend(JavaPackage p, String name){
		p.fullyQualifiedPackageName+"."+name
	}
	
	def static hasAnnotation(IdentifiableAnnotatedJavaStructure ajs, String fqn){
		ajs.annotations.exists(a | fqn.equals(a.annotationType.fullyQualifiedTypeName)); 
	}
	def static symbol(FieldMetadata f){
		f.fieldName.symbol
	}
	
	def static symbol(String s){
		new JavaSymbolName(s)
	}
	
	def static params(MethodMetadata methodMetadata){
		methodMetadata.parameterNames.counter.map ( 
			i |	param(methodMetadata.parameterTypes.get(i).javaType, methodMetadata.parameterNames.get(i))
		)
	}
}